<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>深度学习 | GAN，什么是生成对抗网络 | Justlovesmile's BLOG</title><meta name="keywords" content="深度学习,交叉熵"><meta name="author" content="Justlovesmile,865717150@qq.com"><meta name="copyright" content="Justlovesmile"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="2014年，arXiv上面刊载了一篇关于生成对抗网络的文章，名为《Generative Adversarial Nets》，作者是深度学习领域的大牛Ian J. Goodfellow。本文主要记录博主对于GAN及其基础变种的学习笔记，主要包括GAN，DCGAN的原理和实例，以及WGAN的基础原理。"><meta property="og:type" content="article"><meta property="og:title" content="深度学习 | GAN，什么是生成对抗网络"><meta property="og:url" content="https://blog.justlovesmile.top/posts/6a054795.html"><meta property="og:site_name" content="Justlovesmile&#39;s BLOG"><meta property="og:description" content="2014年，arXiv上面刊载了一篇关于生成对抗网络的文章，名为《Generative Adversarial Nets》，作者是深度学习领域的大牛Ian J. Goodfellow。本文主要记录博主对于GAN及其基础变种的学习笔记，主要包括GAN，DCGAN的原理和实例，以及WGAN的基础原理。"><meta property="og:locale" content="zh_CN"><meta property="og:image" content="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210226103604.jpg"><meta property="article:published_time" content="2021-03-03T02:43:37.000Z"><meta property="article:modified_time" content="2021-03-03T02:43:37.000Z"><meta property="article:author" content="Justlovesmile"><meta property="article:tag" content="深度学习"><meta property="article:tag" content="交叉熵"><meta name="twitter:card" content="summary"><meta name="twitter:image" content="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210226103604.jpg"><link rel="shortcut icon" href="/img/logo.jpg"><link rel="canonical" href="https://blog.justlovesmile.top/posts/6a054795"><link rel="preconnect" href="//cdn.jsdelivr.net"><link rel="preconnect" href="//hm.baidu.com"><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload='this.media="all"'><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload='this.media="all"'><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.css" media="print" onload='this.media="all"'><script>var _hmt=_hmt||[];!function(){var e=document.createElement("script");e.src="https://hm.baidu.com/hm.js?a2ee893562999ebad688b0d82daa100a";var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)}()</script><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN/font/family=Titillium+Web.css" media="print" onload='this.media="all"'><script>const GLOBAL_CONFIG={root:"/",algolia:void 0,localSearch:{path:"search.xml",languages:{hits_empty:"找不到您查询的内容：${query}"}},translate:void 0,noticeOutdate:void 0,highlight:{plugin:"highlighjs",highlightCopy:!0,highlightLang:!0,highlightHeightLimit:400},copy:{success:"复制成功",error:"复制错误",noSupport:"浏览器不支持"},relativeDate:{homepage:!1,post:!1},runtime:"天",date_suffix:{just:"刚刚",min:"分钟前",hour:"小时前",day:"天前",month:"个月前"},copyright:{limitCount:100,languages:{author:"作者: Justlovesmile",link:"链接: ",source:"来源: Justlovesmile's BLOG",info:"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},lightbox:"fancybox",Snackbar:{chs_to_cht:"你已切换为繁体",cht_to_chs:"你已切换为简体",day_to_night:"你已切换为深色模式",night_to_day:"你已切换为浅色模式",bgLight:"var(--mj-card-bg)",bgDark:"var(--mj-card-bg)",position:"top-right"},source:{justifiedGallery:{js:"https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.js",css:"https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.css"}},isPhotoFigcaption:!1,islazyload:!0,isAnchor:!1}</script><script id="config-diff">var GLOBAL_CONFIG_SITE={title:"深度学习 | GAN，什么是生成对抗网络",isPost:!0,isHome:!1,isHighlightShrink:!1,isToc:!0,postUpdate:"2021-03-03 10:43:37"}</script><noscript><style>#nav{opacity:1}.justified-gallery img{opacity:1}#post-meta time,#recent-posts time{display:inline!important}</style></noscript><script>(e=>{e.saveToLocal={set:function(e,t,o){if(0===o)return;const a=864e5*o,n={value:t,expiry:(new Date).getTime()+a};localStorage.setItem(e,JSON.stringify(n))},get:function(e){const t=localStorage.getItem(e);if(!t)return;const o=JSON.parse(t);if(!((new Date).getTime()>o.expiry))return o.value;localStorage.removeItem(e)}},e.getScript=e=>new Promise((t,o)=>{const a=document.createElement("script");a.src=e,a.async=!0,a.onerror=o,a.onload=a.onreadystatechange=function(){const e=this.readyState;e&&"loaded"!==e&&"complete"!==e||(a.onload=a.onreadystatechange=null,t())},document.head.appendChild(a)}),e.activateDarkMode=function(){document.documentElement.setAttribute("data-theme","dark"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","#0d0d0d")},e.activateLightMode=function(){document.documentElement.setAttribute("data-theme","light"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","#ffffff")};const t=saveToLocal.get("theme"),o=(new Date).getHours();void 0===t?o<=6||o>=18?activateDarkMode():activateLightMode():"light"===t?activateLightMode():activateDarkMode();/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)&&document.documentElement.classList.add("apple")})(window)</script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome-animation@0.2.1/dist/font-awesome-animation.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.css"><link rel="stylesheet" href="/css/justlovesmile.css"><link rel="stylesheet" href="/css/blogicon.css"><meta name="generator" content="Hexo 5.4.0"><link rel="alternate" href="/atom.xml" title="Justlovesmile's BLOG" type="application/atom+xml"></head><body><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="" data-lazy-src="/img/avatar.jpg" onerror='onerror=null,src="/img/friend_404.gif"' alt="avatar"></div><div class="site-data is-center"><div class="data-item"><a href="/archives/"><div class="headline">文章</div><div class="length-num">75</div></a></div><div class="data-item"><a href="/tags/"><div class="headline">标签</div><div class="length-num">69</div></a></div><div class="data-item"><a href="/categories/"><div class="headline">分类</div><div class="length-num">6</div></a></div></div><hr><div class="menus_items"><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><span>网站</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/"><i class="fa-fw fas fa-home"></i> <span>首页</span></a></li><li><a class="site-page child" href="/guestbook/"><i class="fa-fw fas fa-pencil-alt"></i> <span>留言</span></a></li><li><a class="site-page child" href="/friends/"><i class="fa-fw fas fa-paper-plane"></i> <span>友链</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><span>文库</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/tags/"><i class="fa-fw fas fa-tags"></i> <span>全部标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fas fa-folder-open"></i> <span>全部分类</span></a></li><li><a class="site-page child" href="/archives/"><i class="fa-fw fas fa-calendar"></i> <span>文章列表</span></a></li><li><a class="site-page child" href="/random/"><i class="fa-fw fas fa-shoe-prints"></i> <span>随便逛逛</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><span>实验室</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/laboratory/"><i class="fa-fw fa fa-lightbulb-o"></i> <span>项目展示</span></a></li><li><a class="site-page child" href="/fcircle/"><i class="fa-fw fa fa-puzzle-piece"></i> <span>友链订阅</span></a></li><li><a class="site-page child" href="/charts/"><i class="fa-fw fa fa-pie-chart"></i> <span>博客统计</span></a></li><li><a class="site-page child" href="/update/"><i class="fa-fw fa fa-commenting-o"></i> <span>更新日志</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><span>清单</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/photos/"><i class="fa-fw fas fa-camera-retro"></i> <span>相册</span></a></li><li><a class="site-page child" href="/video/"><i class="fa-fw fa fa-video-camera"></i> <span>视频</span></a></li><li><a class="site-page child" href="/music/"><i class="fa-fw fas fa-music"></i> <span>歌单</span></a></li><li><a class="site-page child" href="/focus/"><i class="fa-fw fa fa-check-square-o"></i> <span>关注</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><span>关于</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/about/"><i class="fa-fw fas fa-user"></i> <span>本站</span></a></li><li><a class="site-page child" href="/love/"><i class="fa-fw fa fa-heart"></i> <span>Love</span></a></li><li><a class="site-page child" href="/donate/"><i class="fa-fw fa fa-gratipay"></i> <span>打赏</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image:url(https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210226103604.jpg)"><nav id="nav"><div id="nav-group"><div id="blog_name"><a id="site-name" href="/">Justlovesmile</a></div><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><span>网站</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/"><i class="fa-fw fas fa-home"></i> <span>首页</span></a></li><li><a class="site-page child" href="/guestbook/"><i class="fa-fw fas fa-pencil-alt"></i> <span>留言</span></a></li><li><a class="site-page child" href="/friends/"><i class="fa-fw fas fa-paper-plane"></i> <span>友链</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><span>文库</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/tags/"><i class="fa-fw fas fa-tags"></i> <span>全部标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fas fa-folder-open"></i> <span>全部分类</span></a></li><li><a class="site-page child" href="/archives/"><i class="fa-fw fas fa-calendar"></i> <span>文章列表</span></a></li><li><a class="site-page child" href="/random/"><i class="fa-fw fas fa-shoe-prints"></i> <span>随便逛逛</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><span>实验室</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/laboratory/"><i class="fa-fw fa fa-lightbulb-o"></i> <span>项目展示</span></a></li><li><a class="site-page child" href="/fcircle/"><i class="fa-fw fa fa-puzzle-piece"></i> <span>友链订阅</span></a></li><li><a class="site-page child" href="/charts/"><i class="fa-fw fa fa-pie-chart"></i> <span>博客统计</span></a></li><li><a class="site-page child" href="/update/"><i class="fa-fw fa fa-commenting-o"></i> <span>更新日志</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><span>清单</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/photos/"><i class="fa-fw fas fa-camera-retro"></i> <span>相册</span></a></li><li><a class="site-page child" href="/video/"><i class="fa-fw fa fa-video-camera"></i> <span>视频</span></a></li><li><a class="site-page child" href="/music/"><i class="fa-fw fas fa-music"></i> <span>歌单</span></a></li><li><a class="site-page child" href="/focus/"><i class="fa-fw fa fa-check-square-o"></i> <span>关注</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><span>关于</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/about/"><i class="fa-fw fas fa-user"></i> <span>本站</span></a></li><li><a class="site-page child" href="/love/"><i class="fa-fw fa fa-heart"></i> <span>Love</span></a></li><li><a class="site-page child" href="/donate/"><i class="fa-fw fa fa-gratipay"></i> <span>打赏</span></a></li></ul></div></div></div><div id="nav-right"><div id="search-button"><a class="nav-rightbutton site-page social-icon search"><i class="fas fa-search fa-fw"></i></a></div><div id="darkmode_navswitch"><a class="nav-rightbutton site-page darkmode_switchbutton" onclick="switchDarkMode()"><i class="fas fa-adjust"></i></a></div><div id="toggle-menu"><a class="nav-rightbutton site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></div></nav><div class="coverdiv" id="coverdiv"><img class="cover entered loading" id="post-cover" alt="cover" src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210226103604.jpg"></div><div id="post-info"><div class="post-firstinfo" id="post-meta"><span class="post-meta-categories"><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/">人工智能</a></span><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/">#深度学习</a><a class="post-meta__tags" href="/tags/%E4%BA%A4%E5%8F%89%E7%86%B5/">#交叉熵</a></div></div><h1 class="post-title">深度学习 | GAN，什么是生成对抗网络</h1><div id="post-meta"><div class="meta-firstline"><span class="meta-share-time"><span class="meta-avatar"><a class="meta-avatar-img" href="/about/" title="关于作者"><img alt="作者头像" src="" data-lazy-src="/img/avatar.jpg"></a><a class="meta-avatar-name" href="/about/" title="关于作者">Justlovesmile</a></span></span><span class="post-meta-date"><i class="fa-fw post-meta-icon far fa-calendar-alt"></i><span class="post-meta-label">发表于</span><time datetime="2021-03-03T02:43:37.000Z" title="发表于 2021-03-03 10:43:37">2021-03-03</time></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">3k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>14分钟</span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="GAN学习笔记"><a href="#GAN学习笔记" class="headerlink" title="GAN学习笔记"></a>GAN学习笔记</h1><h2 id="1-GAN原理"><a href="#1-GAN原理" class="headerlink" title="1. GAN原理"></a>1. GAN原理</h2><p>论文链接：<a target="_blank" rel="external nofollow noopener noreferrer" href="https://arxiv.org/abs/1406.2661">Generative Adversarial Networks</a></p><blockquote><p>生成式对抗网络(GAN, Generative Adversarial Networks)是一种深度学习模型，是近年来复杂分布上无监督学习最具前景的方法之一。模型通过框架中（至少）两个模块：生成模型（Generative Model）和判别模型（Discriminative Model）的互相博弈学习产生相当好的输出。原始 GAN 理论中，并不要求 G 和 D 都是神经网络，只需要是能拟合相应生成和判别的函数即可。但实用中一般均使用深度神经网络作为 G 和 D 。一个优秀的GAN应用需要有良好的训练方法，否则可能由于神经网络模型的自由性而导致输出不理想。<br>Ian J. Goodfellow等人于2014年10月在<a target="_blank" rel="external nofollow noopener noreferrer" href="https://arxiv.org/abs/1406.2661">Generative Adversarial Networks</a>中提出了一个通过对抗过程估计生成模型的新框架。框架中同时训练两个模型：捕获数据分布的生成模型G，和估计样本来自训练数据的概率的判别模型D。G的训练程序是将D错误的概率最大化。这个框架对应一个最大值集下限的双方对抗游戏。可以证明在任意函数G和D的空间中，存在唯一的解决方案，使得G重现训练数据分布，而D=0.5。在G和D由多层感知器定义的情况下，整个系统可以用反向传播进行训练。在训练或生成样本期间，不需要任何马尔科夫链或展开的近似推理网络。实验通过对生成的样品的定性和定量评估证明了本框架的潜力。<br>—- 摘自<a target="_blank" rel="external nofollow noopener noreferrer" href="https://baike.baidu.com/item/Gan/22181905?fr=aladdin">百度百科</a></p></blockquote><p>GAN是由两部分组成的，第一部分是生成，第二部分是对抗。简单来说，就是有一个生成网络G和一个判别网络D，通过训练让两个网络相互竞争，生成网络G接受一个随机噪声z来生成假的数据G(z)，对抗网络D通过判别器去判别真伪概率，最后希望生成器G生成的数据能够以假乱真。在最理想的状态下，D(G(z)) = 0.5。</p><p>以上原理的数学公式为：</p><p>$$ min_{G}max_{D}V(D,G) = \mathbb{E} _ {x \sim p_{data}(x)} [\log D(x)] + \mathbb{E} _ {z \sim p_{z}(z) [\log (1-D(G(z)))]} $$</p><p>式子中，x表示真实数据，z表示噪声，G(z)表示G网络根据z生成的数据，D(x)表示D网络判断真实数据是否为真的概率，因此D(x)接近1越好。而D(G(z))代表D网络判断G网络生成的虚假数据是真实的概率。<br>因此，对于D网络(辨别器)：</p><ul><li>如果x来自$P_{data}$，那么D(x)要越大越好，可以用$\log(D(x)) \uparrow$表示。</li><li>如果x来自于$P_{generator}$，那么D(G(z))越小越好，进而表示为$\log[1−D(G(z))] \uparrow$。</li><li>因此需要最大化$max_D$<br>对于G网络(生成器)：</li><li>$D(G(z))$越大越好，进而表示为log[1−D(G(z))]↓</li><li>因此需要最小化$min_{G}$。</li></ul><p><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210223180633.png"></p><p>第一步我们训练D，D是希望V(D,G)越大越好，所以是加上梯度(ascending)。第二步训练G时，V(D,G)越小越好，所以是减去梯度(descending)。整个训练过程交替进行。</p><h2 id="2-GAN实例"><a href="#2-GAN实例" class="headerlink" title="2. GAN实例"></a>2. GAN实例</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> torch</span><br><span class="line"><span class="keyword">from</span> torch <span class="keyword">import</span> nn,optim</span><br><span class="line"><span class="keyword">import</span> torchvision.transforms <span class="keyword">as</span> tfs</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> PIL <span class="keyword">import</span> Image</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">from</span> tqdm.auto <span class="keyword">import</span> tqdm</span><br><span class="line"></span><br><span class="line">transforms = tfs.Compose([</span><br><span class="line">    tfs.Resize((<span class="number">32</span>,<span class="number">32</span>)),</span><br><span class="line">    tfs.ToTensor(),</span><br><span class="line">    <span class="comment">#tfs.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])</span></span><br><span class="line">])</span><br><span class="line"></span><br><span class="line">flat_img = <span class="number">32</span>*<span class="number">32</span>*<span class="number">3</span></span><br><span class="line">noise_dim = <span class="number">100</span></span><br><span class="line"></span><br><span class="line">img = Image.<span class="built_in">open</span>(<span class="string">&#x27;1.jpg&#x27;</span>)</span><br><span class="line">real_img = transforms(img)</span><br><span class="line"></span><br><span class="line">torch.manual_seed(<span class="number">2</span>)</span><br><span class="line">fake_img = torch.rand(<span class="number">1</span>,noise_dim)</span><br><span class="line"></span><br><span class="line">plt.imshow(np.transpose(real_img.numpy(),(<span class="number">1</span>,<span class="number">2</span>,<span class="number">0</span>)))</span><br><span class="line"><span class="comment">#print(real_img)</span></span><br></pre></td></tr></table></figure><p><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210224172221.png"></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Discriminator</span>(<span class="params">nn.Module</span>):</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self</span>):</span></span><br><span class="line">        <span class="built_in">super</span>().__init__()</span><br><span class="line">        self.linear = nn.Sequential(</span><br><span class="line">            nn.Linear(flat_img, <span class="number">1024</span>),</span><br><span class="line">            nn.ReLU(),</span><br><span class="line">            nn.Linear(<span class="number">1024</span>, <span class="number">2048</span>),</span><br><span class="line">            nn.ReLU(),</span><br><span class="line">            nn.Linear(<span class="number">2048</span>, <span class="number">1</span>),</span><br><span class="line">            nn.Sigmoid() <span class="comment">#sigmoid常用于二分类问题</span></span><br><span class="line">        )</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">forward</span>(<span class="params">self, img</span>):</span></span><br><span class="line">        img = img.view(<span class="number">1</span>, -<span class="number">1</span>)</span><br><span class="line">        out = self.linear(img)</span><br><span class="line">        <span class="keyword">return</span> out</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Generator</span>(<span class="params">nn.Module</span>):</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self</span>):</span></span><br><span class="line">        <span class="built_in">super</span>().__init__()</span><br><span class="line">        self.linear = nn.Sequential(</span><br><span class="line">            nn.Linear(noise_dim, <span class="number">1024</span>),</span><br><span class="line">            nn.LeakyReLU(),</span><br><span class="line">            nn.Linear(<span class="number">1024</span>, <span class="number">2048</span>),</span><br><span class="line">            nn.LeakyReLU(),</span><br><span class="line">            nn.Linear(<span class="number">2048</span>, flat_img)</span><br><span class="line">        )</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">forward</span>(<span class="params">self, latent_space</span>):</span></span><br><span class="line">        latent_space = latent_space.view(<span class="number">1</span>, -<span class="number">1</span>)</span><br><span class="line">        out = self.linear(latent_space)</span><br><span class="line">        <span class="keyword">return</span> out</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">device = <span class="string">&#x27;cuda:0&#x27;</span> <span class="keyword">if</span> torch.cuda.is_available() <span class="keyword">else</span> <span class="string">&#x27;cpu&#x27;</span></span><br><span class="line"></span><br><span class="line">discr = Discriminator().to(device)</span><br><span class="line">gen = Generator().to(device)</span><br><span class="line"></span><br><span class="line">opt_d = optim.SGD(discr.parameters(), lr=<span class="number">0.001</span>, momentum=<span class="number">0.9</span>)</span><br><span class="line">opt_g = optim.SGD(gen.parameters(), lr=<span class="number">0.001</span>, momentum=<span class="number">0.9</span>)</span><br><span class="line"></span><br><span class="line">criterion = nn.BCELoss()</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line">epochs = <span class="number">200</span></span><br><span class="line">discr_e = <span class="number">4</span></span><br><span class="line">gen_e = <span class="number">4</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#whole model training starts here</span></span><br><span class="line"><span class="keyword">for</span> epoch <span class="keyword">in</span> <span class="built_in">range</span>(epochs):</span><br><span class="line"></span><br><span class="line">    <span class="comment">#discriminator training</span></span><br><span class="line">    <span class="keyword">for</span> k <span class="keyword">in</span> <span class="built_in">range</span>(discr_e):</span><br><span class="line">        out_d1 = discr(real_img.to(device))</span><br><span class="line">        <span class="comment">#loss for real image</span></span><br><span class="line">        loss_d1 = criterion(out_d1, torch.ones((<span class="number">1</span>, <span class="number">1</span>)).to(device))</span><br><span class="line"></span><br><span class="line">        out_d2 = gen(fake_img.to(device)).detach()</span><br><span class="line">        <span class="comment">#loss for fake image</span></span><br><span class="line">        loss_d2 = criterion(discr(out_d2.to(device)), torch.zeros((<span class="number">1</span>, <span class="number">1</span>)).to(device))</span><br><span class="line"></span><br><span class="line">        opt_d.zero_grad()</span><br><span class="line">        loss_d = loss_d1+loss_d2</span><br><span class="line">        loss_d.backward()</span><br><span class="line">        opt_d.step()</span><br><span class="line"></span><br><span class="line">    <span class="comment">#generator training</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(gen_e):</span><br><span class="line">        out_g = gen(fake_img.to(device))</span><br><span class="line">        <span class="comment">#Binary cross entropy loss</span></span><br><span class="line">        loss_g = criterion(discr(out_g.to(device)), torch.ones(<span class="number">1</span>, <span class="number">1</span>).to(device))</span><br><span class="line">        <span class="comment">#Loss function in the GAN paper</span></span><br><span class="line">        <span class="comment">#[log(1 - D(G(z)))]</span></span><br><span class="line">        <span class="comment">#loss_g = torch.log(torch.ones(1, 1).to(device) - (discr(out_g.to(device))))</span></span><br><span class="line">        </span><br><span class="line">        opt_g.zero_grad()</span><br><span class="line">        loss_g.backward()</span><br><span class="line">        opt_g.step()</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span> (epoch+<span class="number">1</span>)%<span class="number">10</span>==<span class="number">0</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;Epoch[&#123;&#125;/&#123;&#125;],d_loss:&#123;:.6f&#125;,g_loss:&#123;:.6f&#125;&#x27;</span>.<span class="built_in">format</span>(epoch+<span class="number">1</span>,epochs,loss_d.data.item(),loss_g.data.item()))</span><br><span class="line"></span><br><span class="line">out=gen(fake_img.to(device)).detach()</span><br><span class="line">out_score=discr(out_g.to(device))</span><br><span class="line">loss = criterion(out_score, torch.ones(<span class="number">1</span>, <span class="number">1</span>).to(device))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;score:&quot;</span>,out_score.item(),<span class="string">&quot;loss:&quot;</span>,loss.item())</span><br><span class="line"></span><br><span class="line">out=out.reshape((<span class="number">3</span>,<span class="number">32</span>,<span class="number">32</span>)).cpu()</span><br><span class="line"></span><br><span class="line"><span class="comment">#print(out)</span></span><br><span class="line">plt.subplot(<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>)</span><br><span class="line">plt.title(<span class="string">&#x27;fake&#x27;</span>)</span><br><span class="line">plt.imshow(np.transpose(out.numpy(),(<span class="number">1</span>,<span class="number">2</span>,<span class="number">0</span>)))</span><br><span class="line">plt.subplot(<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>)</span><br><span class="line">plt.title(<span class="string">&#x27;real&#x27;</span>)</span><br><span class="line">plt.imshow(np.transpose(real_img.numpy(),(<span class="number">1</span>,<span class="number">2</span>,<span class="number">0</span>)))</span><br></pre></td></tr></table></figure><p><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210224183510.png"></p><h2 id="3-DCGAN原理"><a href="#3-DCGAN原理" class="headerlink" title="3. DCGAN原理"></a>3. DCGAN原理</h2><p><a target="_blank" rel="external nofollow noopener noreferrer" href="https://arxiv.org/pdf/1511.06434.pdf">https://arxiv.org/pdf/1511.06434.pdf</a></p><p>DCGAN的原理和GAN是一样的。只不过DCGANs体系结构有所改变：</p><ul><li>使用指定步长的卷积层代替池化层</li><li>在生成器和鉴别器中使用batch norm。</li><li>移除全连接层，以实现更深层次的体系结构，减少参数。</li><li>在生成器中使用ReLU激活，但输出使用Tanh。</li><li>在鉴别器中使用LeakyReLU激活</li></ul><p><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210224183753.png"></p><p>DCGAN中提到了网络的训练细节：</p><ul><li>使用Adam算法更新参数，betas=(0.5, 0.999)；</li><li>batch size选为128；</li><li>权重使用正太分布，均值为0，标准差为0.02；</li><li>学习率0.0002。</li></ul><h2 id="4-DCGAN实例"><a href="#4-DCGAN实例" class="headerlink" title="4. DCGAN实例"></a>4. DCGAN实例</h2><p>生成动漫头像，数据集来自<a target="_blank" rel="external nofollow noopener noreferrer" href="https://www.kaggle.com/soumikrakshit/anime-faces">https://www.kaggle.com/soumikrakshit/anime-faces</a></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> imageio</span><br><span class="line"><span class="keyword">from</span> tqdm.auto <span class="keyword">import</span> tqdm</span><br><span class="line"><span class="keyword">import</span> torch,torchvision</span><br><span class="line"><span class="keyword">import</span> torch.nn <span class="keyword">as</span> nn</span><br><span class="line"><span class="keyword">from</span> torch.utils.data <span class="keyword">import</span> Dataset, DataLoader</span><br><span class="line"><span class="keyword">from</span> torchvision <span class="keyword">import</span> transforms, utils</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line">avatar_img_path = <span class="string">&quot;E:/python/dataset/anime face/data&quot;</span></span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">trans = transforms.Compose([</span><br><span class="line">    transforms.ToTensor(),</span><br><span class="line">    transforms.Normalize((<span class="number">0.5</span>, <span class="number">0.5</span>, <span class="number">0.5</span>), (<span class="number">0.5</span>, <span class="number">0.5</span>, <span class="number">0.5</span>))</span><br><span class="line">])</span><br><span class="line"></span><br><span class="line">noise_dim = <span class="number">100</span></span><br><span class="line">batch_size = <span class="number">16</span></span><br><span class="line">beta1=<span class="number">0.5</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">#自定义数据集</span></span><br><span class="line"><span class="string">file_train=[]</span></span><br><span class="line"><span class="string">for image_name in tqdm(os.listdir(avatar_img_path)):</span></span><br><span class="line"><span class="string">    file_train.append(os.path.join(avatar_img_path,image_name))</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">def default_loader(path):</span></span><br><span class="line"><span class="string">    img = imageio.imread(path)</span></span><br><span class="line"><span class="string">    img = img/255</span></span><br><span class="line"><span class="string">    img = trans(img)</span></span><br><span class="line"><span class="string">    return img</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">class trainset(Dataset):</span></span><br><span class="line"><span class="string">    def __init__(self, loader=default_loader):</span></span><br><span class="line"><span class="string">    #定义好 image 的路径</span></span><br><span class="line"><span class="string">        self.images = file_train</span></span><br><span class="line"><span class="string">        self.target = 0</span></span><br><span class="line"><span class="string">        self.loader = loader</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    def __getitem__(self, index):</span></span><br><span class="line"><span class="string">        fn = self.images[index]</span></span><br><span class="line"><span class="string">        img = self.loader(fn)</span></span><br><span class="line"><span class="string">        target = self.target</span></span><br><span class="line"><span class="string">        return img,target</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">    def __len__(self):</span></span><br><span class="line"><span class="string">        return len(self.images)</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">img_dataset=torchvision.datasets.ImageFolder(<span class="string">&quot;E:/python/dataset/anime face&quot;</span>, transform=trans)</span><br><span class="line"><span class="comment">#img_dataset=trainset()</span></span><br><span class="line">img_dataloader=DataLoader(img_dataset,batch_size=batch_size,shuffle=<span class="literal">True</span>)</span><br><span class="line"><span class="comment">#print(img_dataset)</span></span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Generator</span>(<span class="params">nn.Module</span>):</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self, z_dim</span>):</span></span><br><span class="line">        <span class="built_in">super</span>(Generator,self).__init__()</span><br><span class="line">        self.z_dim = z_dim</span><br><span class="line">        self.generator = nn.Sequential(</span><br><span class="line">            nn.ConvTranspose2d(self.z_dim,<span class="number">512</span>,<span class="number">4</span>,<span class="number">1</span>,<span class="number">0</span>,bias=<span class="literal">False</span>),</span><br><span class="line">            nn.BatchNorm2d(num_features=<span class="number">512</span>),</span><br><span class="line">            nn.ReLU(<span class="literal">True</span>),</span><br><span class="line">            nn.ConvTranspose2d(<span class="number">512</span>,<span class="number">256</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">1</span>,bias=<span class="literal">False</span>),</span><br><span class="line">            nn.BatchNorm2d(num_features=<span class="number">256</span>),</span><br><span class="line">            nn.ReLU(<span class="literal">True</span>),</span><br><span class="line">            nn.ConvTranspose2d(<span class="number">256</span>,<span class="number">128</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">1</span>,bias=<span class="literal">False</span>),</span><br><span class="line">            nn.BatchNorm2d(num_features=<span class="number">128</span>),</span><br><span class="line">            nn.ReLU(<span class="literal">True</span>),</span><br><span class="line">            nn.ConvTranspose2d(<span class="number">128</span>,<span class="number">64</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">1</span>,bias=<span class="literal">False</span>),</span><br><span class="line">            nn.BatchNorm2d(num_features=<span class="number">64</span>),</span><br><span class="line">            nn.ReLU(<span class="literal">True</span>),</span><br><span class="line">            nn.ConvTranspose2d(<span class="number">64</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">1</span>,bias=<span class="literal">False</span>),</span><br><span class="line">            nn.Tanh()</span><br><span class="line">        )</span><br><span class="line">        self.weight_init()</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">weight_init</span>(<span class="params">self</span>):</span></span><br><span class="line">        <span class="keyword">for</span> m <span class="keyword">in</span> self.generator.modules():</span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">isinstance</span>(m, nn.ConvTranspose2d):</span><br><span class="line">                nn.init.normal_(m.weight.data, <span class="number">0</span>, <span class="number">0.02</span>)</span><br><span class="line"></span><br><span class="line">            <span class="keyword">elif</span> <span class="built_in">isinstance</span>(m, nn.BatchNorm2d):</span><br><span class="line">                nn.init.normal_(m.weight.data, <span class="number">0</span>, <span class="number">0.02</span>)</span><br><span class="line">                nn.init.constant_(m.bias.data, <span class="number">0</span>)</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">forward</span>(<span class="params">self, x</span>):</span></span><br><span class="line">        out = self.generator(x)</span><br><span class="line">        <span class="keyword">return</span> out</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Discriminator</span>(<span class="params">nn.Module</span>):</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self</span>):</span></span><br><span class="line">        <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">        initialize</span></span><br><span class="line"><span class="string">        </span></span><br><span class="line"><span class="string">        :param image_size: tuple (3, h, w)</span></span><br><span class="line"><span class="string">        &quot;&quot;&quot;</span></span><br><span class="line">        <span class="built_in">super</span>(Discriminator,self).__init__()</span><br><span class="line">        self.discriminator = nn.Sequential(</span><br><span class="line">            nn.Conv2d(<span class="number">3</span>,<span class="number">64</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">1</span>,bias=<span class="literal">False</span>),</span><br><span class="line">            nn.BatchNorm2d(num_features=<span class="number">64</span>),</span><br><span class="line">            nn.LeakyReLU(<span class="number">0.2</span>),</span><br><span class="line">            nn.Conv2d(<span class="number">64</span>,<span class="number">128</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">1</span>,bias=<span class="literal">False</span>),</span><br><span class="line">            nn.BatchNorm2d(num_features=<span class="number">128</span>),</span><br><span class="line">            nn.LeakyReLU(<span class="number">0.2</span>),</span><br><span class="line">            nn.Conv2d(<span class="number">128</span>,<span class="number">256</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">1</span>,bias=<span class="literal">False</span>),</span><br><span class="line">            nn.BatchNorm2d(num_features=<span class="number">256</span>),</span><br><span class="line">            nn.LeakyReLU(<span class="number">0.2</span>),</span><br><span class="line">            nn.Conv2d(<span class="number">256</span>,<span class="number">512</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">1</span>,bias=<span class="literal">False</span>),</span><br><span class="line">            nn.BatchNorm2d(num_features=<span class="number">512</span>),</span><br><span class="line">            nn.LeakyReLU(<span class="number">0.2</span>),</span><br><span class="line">            nn.Conv2d(<span class="number">512</span>,<span class="number">1</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">0</span>,bias=<span class="literal">False</span>),</span><br><span class="line">            nn.Sigmoid()</span><br><span class="line">        )</span><br><span class="line">        self.weight_init()</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">weight_init</span>(<span class="params">self</span>):</span></span><br><span class="line">        <span class="keyword">for</span> m <span class="keyword">in</span> self.discriminator.modules():</span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">isinstance</span>(m, nn.ConvTranspose2d):</span><br><span class="line">                nn.init.normal_(m.weight.data, <span class="number">0</span>, <span class="number">0.02</span>)</span><br><span class="line"></span><br><span class="line">            <span class="keyword">elif</span> <span class="built_in">isinstance</span>(m, nn.BatchNorm2d):</span><br><span class="line">                nn.init.normal_(m.weight.data, <span class="number">0</span>, <span class="number">0.02</span>)</span><br><span class="line">                nn.init.constant_(m.bias.data, <span class="number">0</span>)</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">forward</span>(<span class="params">self, x</span>):</span></span><br><span class="line">        out = self.discriminator(x)</span><br><span class="line">        out = out.view(x.size(<span class="number">0</span>), -<span class="number">1</span>)</span><br><span class="line">        <span class="keyword">return</span> out</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">device = torch.device(<span class="string">&quot;cuda:0&quot;</span> <span class="keyword">if</span> torch.cuda.is_available <span class="keyword">else</span> <span class="string">&quot;cpu&quot;</span>)</span><br><span class="line"></span><br><span class="line">generator = Generator(noise_dim).to(device)</span><br><span class="line">discriminator = Discriminator().to(device)</span><br><span class="line"></span><br><span class="line">bce_loss = nn.BCELoss()</span><br><span class="line"><span class="comment">#optimizer_D = torch.optim.Adam(discriminator.parameters(), lr=0.0002, betas=(beta1, 0.999))</span></span><br><span class="line">optimizer_D = torch.optim.Adam(discriminator.parameters(), lr=<span class="number">0.00005</span>, betas=(beta1, <span class="number">0.999</span>))</span><br><span class="line">optimizer_G = torch.optim.Adam(generator.parameters(), lr=<span class="number">0.0002</span>, betas=(beta1, <span class="number">0.999</span>))</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line">epochs=<span class="number">20</span></span><br><span class="line"></span><br><span class="line">fixed_z=torch.randn(batch_size,noise_dim,<span class="number">1</span>,<span class="number">1</span>,device=device)</span><br><span class="line"><span class="keyword">for</span> epoch <span class="keyword">in</span> <span class="built_in">range</span>(epochs):</span><br><span class="line">    <span class="keyword">for</span> step,(image,_) <span class="keyword">in</span> <span class="built_in">enumerate</span>(img_dataloader):</span><br><span class="line">        batch_size=image.size(<span class="number">0</span>)</span><br><span class="line">        <span class="comment">#=====训练辨别器====</span></span><br><span class="line">        optimizer_D.zero_grad()</span><br><span class="line">        <span class="comment"># 计算判别器对真实样本给出为真的概率</span></span><br><span class="line">        d_out_real = discriminator(image.<span class="built_in">type</span>(torch.FloatTensor).to(device))</span><br><span class="line">        real_loss = bce_loss(d_out_real, torch.ones(size=(batch_size, <span class="number">1</span>)).to(device))</span><br><span class="line">        real_scores = d_out_real</span><br><span class="line">        <span class="comment">#real_loss.backward()</span></span><br><span class="line">        <span class="comment"># 计算判别器对假样本给出为真的概率</span></span><br><span class="line">        noise = torch.randn(batch_size,noise_dim,<span class="number">1</span>,<span class="number">1</span>,device=device)</span><br><span class="line">        fake_img = generator(noise)</span><br><span class="line">        d_out_fake = discriminator(fake_img.detach())</span><br><span class="line">        fake_loss = bce_loss(d_out_fake, torch.zeros(size=(batch_size, <span class="number">1</span>)).to(device))</span><br><span class="line">        fake_scores = d_out_fake</span><br><span class="line">        <span class="comment">#fake_loss.backward()</span></span><br><span class="line">        <span class="comment"># 更新判别器参数</span></span><br><span class="line">        d_loss = (real_loss + fake_loss)/<span class="number">2</span></span><br><span class="line">        d_loss.backward()</span><br><span class="line">        optimizer_D.step()</span><br><span class="line">        </span><br><span class="line">        <span class="comment">#=====训练生成器====</span></span><br><span class="line">        optimizer_G.zero_grad()</span><br><span class="line">        <span class="comment"># 计算判别器对伪造样本的输出的为真样本的概率值</span></span><br><span class="line">        d_out_fake = discriminator(fake_img)</span><br><span class="line">        <span class="comment"># 计算生成器伪造样本不被认为是真的损失</span></span><br><span class="line">        g_loss = bce_loss(d_out_fake, torch.ones(size=(batch_size, <span class="number">1</span>)).to(device))</span><br><span class="line">        <span class="comment"># 更新生成器</span></span><br><span class="line">        g_loss.backward()</span><br><span class="line">        optimizer_G.step()</span><br><span class="line"></span><br><span class="line">        <span class="comment"># #################################################</span></span><br><span class="line">        <span class="comment"># 4：打印损失，保存图片</span></span><br><span class="line">        <span class="keyword">if</span> step % <span class="number">200</span> == <span class="number">0</span>:</span><br><span class="line">            generator.<span class="built_in">eval</span>()</span><br><span class="line">            fixed_image = generator(fixed_z)</span><br><span class="line">            generator.train()</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&quot;[epoch: &#123;&#125;/&#123;&#125;], [iter: &#123;&#125;], [G loss: &#123;:.3f&#125;], [D loss: &#123;:.3f&#125;], [R Score: &#123;:.3f&#125;], [F Score: &#123;:.3f&#125;]&quot;</span>.<span class="built_in">format</span>(epoch+<span class="number">1</span>,epochs,step, g_loss.item(), d_loss.item(),real_scores.data.mean(), fake_scores.data.mean()))</span><br><span class="line">            utils.save_image(fixed_image.detach(), <span class="built_in">str</span>(epoch+<span class="number">1</span>)+<span class="string">&quot;fake.jpg&quot;</span>,normalize=<span class="literal">True</span>)</span><br><span class="line">            utils.save_image(image,<span class="built_in">str</span>(epoch+<span class="number">1</span>)+<span class="string">&quot;real.jpg&quot;</span>,normalize=<span class="literal">True</span>)</span><br></pre></td></tr></table></figure><p>结果如下：<br>[epoch: 1/20], [iter: 0], [G loss: 0.699], [D loss: 0.694], [R Score: 0.499], [F Score: 0.500]<br>[epoch: 1/20], [iter: 200], [G loss: 0.803], [D loss: 0.715], [R Score: 0.512], [F Score: 0.529]<br>[epoch: 1/20], [iter: 400], [G loss: 0.734], [D loss: 0.692], [R Score: 0.492], [F Score: 0.491]<br>[epoch: 1/20], [iter: 600], [G loss: 0.730], [D loss: 0.693], [R Score: 0.496], [F Score: 0.496]<br>[epoch: 1/20], [iter: 800], [G loss: 0.748], [D loss: 0.686], [R Score: 0.500], [F Score: 0.492]<br>[epoch: 1/20], [iter: 1000], [G loss: 0.745], [D loss: 0.680], [R Score: 0.514], [F Score: 0.499]<br>[epoch: 1/20], [iter: 1200], [G loss: 0.715], [D loss: 0.701], [R Score: 0.527], [F Score: 0.532]<br>[epoch: 2/20], [iter: 0], [G loss: 0.762], [D loss: 0.679], [R Score: 0.524], [F Score: 0.508]<br>[epoch: 2/20], [iter: 200], [G loss: 0.815], [D loss: 0.686], [R Score: 0.507], [F Score: 0.498]<br>[epoch: 2/20], [iter: 400], [G loss: 0.836], [D loss: 0.665], [R Score: 0.509], [F Score: 0.479]<br>[epoch: 2/20], [iter: 600], [G loss: 0.759], [D loss: 0.694], [R Score: 0.523], [F Score: 0.520]<br>[epoch: 2/20], [iter: 800], [G loss: 0.973], [D loss: 0.646], [R Score: 0.551], [F Score: 0.499]<br>[epoch: 2/20], [iter: 1000], [G loss: 0.926], [D loss: 0.671], [R Score: 0.531], [F Score: 0.495]<br>[epoch: 2/20], [iter: 1200], [G loss: 1.100], [D loss: 0.582], [R Score: 0.497], [F Score: 0.362]</p><p><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210225180739.png"></p><p>第7个epoch：<br><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210226103604.jpg"></p><p>batch_size以及其他参数可自行调整。</p><h2 id="5-WGAN原理"><a href="#5-WGAN原理" class="headerlink" title="5. WGAN原理"></a>5. WGAN原理</h2><p>论文：<a target="_blank" rel="external nofollow noopener noreferrer" href="https://arxiv.org/pdf/1701.07875.pdf">Wasserstein GAN</a><br><a target="_blank" rel="external nofollow noopener noreferrer" href="https://arxiv.org/abs/1701.04862">Towards Principled Methods for Training Generative Adversarial Networks</a></p><p>总所周知，GAN的训练存在很多问题和挑战：</p><ul><li>训练困难，需要精心设计模型结构，协调G和D的训练程度</li><li>G和D的损失函数无法指示训练过程，缺乏一个有意义的指标和生成图片的质量相关联</li><li>模式崩坏（mode collapse），生成的图片虽然看起来像是真的，但是缺乏多样性</li></ul><p>WGAN相比较于传统的GAN，做了如下修改：</p><ul><li>D最后一层去掉sigmoid</li><li>G和D的loss不取log</li><li>每次更新D的参数后，将其绝对值截断到不超过一个固定常数c</li><li>不要用基于动量的优化算法（包括momentum和Adam），推荐RMSProp，SGD也行</li></ul><p><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210303105435.png"></p><p>G的损失函数原本为$\mathbb{E} _ {z \sim p _ z}[\log(1-D(G(z)))]$ ，其导致的结果是，如果D训练得太好，G将学习不到有效的梯度。但是，如果D训练得不够好，G也学习不到有效的梯度。<br>因此以上损失函数导致GAN训练特别不稳定，需要小心协调G和D的训练程度。</p><blockquote><p>WGAN参考资料：<br><a target="_blank" rel="external nofollow noopener noreferrer" href="https://zhuanlan.zhihu.com/p/44169714">https://zhuanlan.zhihu.com/p/44169714</a><br><a target="_blank" rel="external nofollow noopener noreferrer" href="https://www.cnblogs.com/Allen-rg/p/10305125.html">https://www.cnblogs.com/Allen-rg/p/10305125.html</a></p></blockquote></article><div class="post-reward"><div class="reward-button"><i class="fas fa-hamburger"></i> 打赏作者</div><div class="reward-main"><ul class="reward-all"><ul class="reward-group"><li class="reward-item"><a href="/img/wechat.jpg" target="_blank"><img class="post-qr-code-img" src="" data-lazy-src="/img/wechat.jpg" alt="微信"></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="/img/alipay.jpg" target="_blank"><img class="post-qr-code-img" src="" data-lazy-src="/img/alipay.jpg" alt="支付宝"></a><div class="post-qr-code-desc">支付宝</div></li></ul><a class="reward-main-btn" href="/donate"><div class="reward-text">赞赏者名单</div><div class="reward-dec">因为你们的支持让我意识到写文章的价值🙏</div></a></ul></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/">深度学习</a><a class="post-meta__tags" href="/tags/%E4%BA%A4%E5%8F%89%E7%86%B5/">交叉熵</a></div><div class="post_share"><div class="social-share" data-image="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210226103604.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css" media="print" onload='this.media="all"'><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer="defer"></script></div></div><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-info">深度学习 | GAN，什么是生成对抗网络</span></div><div class="post-copyright__type"><span class="post-copyright-info"><a href="https://blog.justlovesmile.top/posts/6a054795.html">https://blog.justlovesmile.top/posts/6a054795.html</a></span></div><div class="post-copyright__notice"><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="external nofollow noopener noreferrer">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://blog.justlovesmile.top" target="_blank">Justlovesmile's BLOG</a>！</span></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/posts/223c1a0c.html"><img class="prev-cover" src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210326105717.png" onerror='onerror=null,src="/img/404.jpg"' alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">iOS快捷指令 | iPicGo，随时随地用手机上传图片到图床</div></div></a></div><div class="next-post pull-right"><a href="/posts/ebe3a70b.html"><img class="next-cover" src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210131105502.jpeg" onerror='onerror=null,src="/img/404.jpg"' alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">深度学习 | Wasserstein距离</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/posts/fdbf585c.html" title="深度学习 | 交叉熵损失函数"><img class="cover" src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20201211225659.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-12-11</div><div class="title">深度学习 | 交叉熵损失函数</div></div></a></div><div><a href="/posts/bb608df3.html" title="目标检测 | RetinaNet，经典单阶段Anchor-Based目标检测模型"><img class="cover" src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20220314113659.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-03-14</div><div class="title">目标检测 | RetinaNet，经典单阶段Anchor-Based目标检测模型</div></div></a></div><div><a href="/posts/fc798de3.html" title="目标检测 | Faster R-CNN，经典两阶段检测模型"><img class="cover" src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20220312220823.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-03-12</div><div class="title">目标检测 | Faster R-CNN，经典两阶段检测模型</div></div></a></div><div><a href="/posts/d150f284.html" title="深度学习 | 小样本学习基础概念"><img class="cover" src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/202201271037441.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-01-27</div><div class="title">深度学习 | 小样本学习基础概念</div></div></a></div><div><a href="/posts/865c56ba.html" title="目标检测 | 常用数据集标注格式及生成脚本"><img class="cover" src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/202109111517311.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-09-11</div><div class="title">目标检测 | 常用数据集标注格式及生成脚本</div></div></a></div><div><a href="/posts/ebe3a70b.html" title="深度学习 | Wasserstein距离"><img class="cover" src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20210131105502.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-01-31</div><div class="title">深度学习 | Wasserstein距离</div></div></a></div></div></div><hr><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i> <span>评论</span></div></div><div class="comment-wrap"><div><div id="twikoo-wrap"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="" data-lazy-src="/img/avatar.jpg" onerror='this.onerror=null,this.src="/img/friend_404.gif"' alt="avatar"></div><div class="author-info__name">Justlovesmile</div><div class="author-info__description">一个计算机专业学生的个人博客，记录着学习笔记和生活中的思考，期待着和所有人相遇</div></div><div class="card-info-data is-center"><div class="card-info-data-item"><a href="/archives/"><div class="headline">文章</div><div class="length-num">75</div></a></div><div class="card-info-data-item"><a href="/tags/"><div class="headline">标签</div><div class="length-num">69</div></a></div><div class="card-info-data-item"><a href="/categories/"><div class="headline">分类</div><div class="length-num">6</div></a></div></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn card-announcement-animation"></i><span>公告</span></div><div class="announcement_content"><p>不定时更新博客，欢迎交换<a href="/friends/"><strong>友链</strong></a>...</p><div class="twopeople"><div class="container" style="height:200px"><canvas class="illo" width="800" height="800" style="max-width:200px;max-height:200px;touch-action:none;width:640px;height:640px"></canvas></div><script src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN/js/twopeople1.js"></script><script src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN/js/zdog.dist.js"></script><script id="rendered-js" src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN/js/twopeople.js"></script><style>.twopeople{margin:0;align-items:center;justify-content:center;text-align:center}canvas{display:block;margin:0 auto;cursor:move}</style></div><div style="text-align:center"><a href="https://www.foreverblog.cn/" target="_blank" rel="external nofollow noopener noreferrer"><img src="" data-lazy-src="https://img.foreverblog.cn/logo_en_default.png" alt="foreverblog" style="width:auto;height:16px"></a></div></div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#GAN%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0"><span class="toc-text">GAN学习笔记</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-GAN%E5%8E%9F%E7%90%86"><span class="toc-text">1. GAN原理</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-GAN%E5%AE%9E%E4%BE%8B"><span class="toc-text">2. GAN实例</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-DCGAN%E5%8E%9F%E7%90%86"><span class="toc-text">3. DCGAN原理</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-DCGAN%E5%AE%9E%E4%BE%8B"><span class="toc-text">4. DCGAN实例</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-WGAN%E5%8E%9F%E7%90%86"><span class="toc-text">5. WGAN原理</span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/posts/56b0563d.html" title="Hexo博客 | 如何让Butterfly主题导航栏居中"><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20220315095300.png" onerror='this.onerror=null,this.src="/img/404.jpg"' alt="Hexo博客 | 如何让Butterfly主题导航栏居中"></a><div class="content"><a class="title" href="/posts/56b0563d.html" title="Hexo博客 | 如何让Butterfly主题导航栏居中">Hexo博客 | 如何让Butterfly主题导航栏居中</a><time datetime="2022-03-15T01:25:18.000Z" title="发表于 2022-03-15 09:25:18">2022-03-15</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/bb608df3.html" title="目标检测 | RetinaNet，经典单阶段Anchor-Based目标检测模型"><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20220314113659.png" onerror='this.onerror=null,this.src="/img/404.jpg"' alt="目标检测 | RetinaNet，经典单阶段Anchor-Based目标检测模型"></a><div class="content"><a class="title" href="/posts/bb608df3.html" title="目标检测 | RetinaNet，经典单阶段Anchor-Based目标检测模型">目标检测 | RetinaNet，经典单阶段Anchor-Based目标检测模型</a><time datetime="2022-03-14T03:26:21.000Z" title="发表于 2022-03-14 11:26:21">2022-03-14</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/fc798de3.html" title="目标检测 | Faster R-CNN，经典两阶段检测模型"><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/20220312220823.png" onerror='this.onerror=null,this.src="/img/404.jpg"' alt="目标检测 | Faster R-CNN，经典两阶段检测模型"></a><div class="content"><a class="title" href="/posts/fc798de3.html" title="目标检测 | Faster R-CNN，经典两阶段检测模型">目标检测 | Faster R-CNN，经典两阶段检测模型</a><time datetime="2022-03-12T13:59:01.000Z" title="发表于 2022-03-12 21:59:01">2022-03-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/d150f284.html" title="深度学习 | 小样本学习基础概念"><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/202201271037441.png" onerror='this.onerror=null,this.src="/img/404.jpg"' alt="深度学习 | 小样本学习基础概念"></a><div class="content"><a class="title" href="/posts/d150f284.html" title="深度学习 | 小样本学习基础概念">深度学习 | 小样本学习基础概念</a><time datetime="2022-01-27T02:24:38.000Z" title="发表于 2022-01-27 10:24:38">2022-01-27</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/e05a9ab6.html" title="Jupyter Lab | 安装、配置、插件推荐、多用户使用教程"><img src="" data-lazy-src="https://cdn.jsdelivr.net/gh/Justlovesmile/CDN2/post/image-20211125175041150.png" onerror='this.onerror=null,this.src="/img/404.jpg"' alt="Jupyter Lab | 安装、配置、插件推荐、多用户使用教程"></a><div class="content"><a class="title" href="/posts/e05a9ab6.html" title="Jupyter Lab | 安装、配置、插件推荐、多用户使用教程">Jupyter Lab | 安装、配置、插件推荐、多用户使用教程</a><time datetime="2021-11-25T09:38:43.000Z" title="发表于 2021-11-25 17:38:43">2021-11-25</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div id="footer_deal"><a class="social-icon" href="mailto:865717150@qq.com" target="_blank" title="Email" rel="external nofollow noopener noreferrer"><i class="fas fa-envelope"></i></a><a class="social-icon" href="https://blog.csdn.net/qq_43701912" target="_blank" title="CSDN" rel="external nofollow noopener noreferrer"><i class="iconfont icon-csdn1"></i></a><a class="social-icon" href="https://github.com/Justlovesmile" target="_blank" title="Github" rel="external nofollow noopener noreferrer"><i class="fab fa-github"></i></a><a class="social-icon" href="https://weibo.com/u/5252319712" target="_blank" title="微博" rel="external nofollow noopener noreferrer"><i class="fa fa-weibo"></i></a><a class="social-icon" href="https://space.bilibili.com/168738824" target="_blank" title="Bilibili" rel="external nofollow noopener noreferrer"><i class="fas iconfont icon-bilibili"></i></a></div><div id="mj-footer"><div class="footer-group"><h3 class="footer-title">关于</h3><div class="footer-links"><a class="footer-item" target="_blank" rel="external nofollow noopener noreferrer" href="https://www.justlovesmile.top/">个人主页</a><a class="footer-item" href="/donate/">赞赏博主</a><a class="footer-item" href="/update/">博客日志</a><a class="footer-item" href="/charts/">博客统计</a></div></div><div class="footer-group"><h3 class="footer-title">归档</h3><div class="footer-links"><a class="footer-item" href="/archives/">文章归档</a><a class="footer-item" href="/tags/">全部标签</a><a class="footer-item" href="/categories/">全部分类</a><a class="footer-item" href="/random/">随机文章</a></div></div><div class="footer-group"><h3 class="footer-title">导航</h3><div class="footer-links"><a class="footer-item" href="/guestbook/">博客留言</a><a class="footer-item" href="/friends/">友情链接</a><a class="footer-item" href="/fcircle/">友链订阅</a><a class="footer-item" href="/atom.xml">RSS订阅</a></div></div><div class="footer-group"><h3 class="footer-title">协议</h3><div class="footer-links"><a class="footer-item" href="/privacy/">隐私协议</a><a class="footer-item" href="/cookies/">Cookies</a><a class="footer-item" href="/cc/">版权协议</a></div></div></div><div id="footer-banner"><div class="footer-banner-links"><div class="footer-banner-left"><div id="footer-banner-tips">©2019 - 2022 By Justlovesmile</div></div><div class="footer-banner-right"><a class="footer-banner-link" target="_blank" rel="external nofollow noopener noreferrer" href="http://beian.miit.gov.cn/">蜀ICP备20004960号</a><a class="footer-banner-link" href="/update/">主题</a><a class="footer-banner-link" href="/about/">关于</a></div></div></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">本地搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i> <span>数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"></div></div><hr><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script defer="defer" src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.js"></script><script defer="defer" src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script defer="defer" src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script defer="defer" src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script defer="defer" src="/js/search/local-search.js"></script><div class="js-pjax"><script>if(window.MathJax)MathJax.startup.document.state(0),MathJax.texReset(),MathJax.typeset();else{window.MathJax={tex:{inlineMath:[["$","$"],["\\(","\\)"]],tags:"ams"},chtml:{scale:1.2},options:{renderActions:{findScript:[10,t=>{for(const e of document.querySelectorAll('script[type^="math/tex"]')){const a=!!e.type.match(/; *mode=display/),n=new t.options.MathItem(e.textContent,t.inputJax[0],a),s=document.createTextNode("");e.parentNode.replaceChild(s,e),n.start={node:s,delim:"",n:0},n.end={node:s,delim:"",n:0},t.math.push(n)}},""],insertScript:[200,()=>{document.querySelectorAll("mjx-container:not([display])").forEach(t=>{const e=t.parentNode;"li"===e.nodeName.toLowerCase()?e.parentNode.classList.add("has-jax"):e.classList.add("has-jax")})},"",!1]}}};const t=document.createElement("script");t.src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js",t.id="MathJax-script",t.async=!0,document.head.appendChild(t)}</script><script>(()=>{const t=()=>{twikoo.init(Object.assign({el:"#twikoo-wrap",envId:"blog-comment-3gt33nkmf9f97e6e",region:"ap-shanghai",onCommentLoaded:function(){btf.loadLightbox(document.querySelectorAll("#twikoo .tk-content img:not(.vemoji)"))}},null))},o=()=>{"object"!=typeof twikoo?getScript("https://cdn.jsdelivr.net/npm/twikoo/dist/twikoo.all.min.js").then(t):setTimeout(t,0)};btf.loadComment(document.getElementById("twikoo-wrap"),o)})()</script></div><canvas id="universe"></canvas><script defer="defer">console.log("\n %c 欢迎来到Justlovesmile の Blog %c https://github.com/Justlovesmile %c https://blog.justlovesmile.top \n","color: #f9ed69; background: #252a34; padding:5px 0;","background: #3fc1c9; padding:5px 0;","background: #3fc1c9; padding:5px 0;")</script><script defer="defer" src="/js/rgbaster.min.js"></script><script defer="defer" src="/js/justlovesmile.js"></script><script>window.addEventListener("load",async()=>{navigator.serviceWorker.register("/js/sw-cdn.js?time="+(new Date).getTime()).then(async e=>{"true"!=window.localStorage.getItem("install")&&(window.localStorage.setItem("install","true"),setTimeout(()=>{window.location.search="?time="+(new Date).getTime()},1e3))}).catch(e=>{console.log("sw-cdn.js error")})})</script></div></body></html>